#!/usr/bin/env python

# (c) 2007-2011 Helsinki University of Technology and University of Helsinki
# Licensed under the MIT license; see LICENSE.txt for more information.

from harava.map import Mapper
from harava.rdf import *
from harava.termassign import assign_terms
import harava.lrucache

import sys
import urllib

ARPAPROJECTS = {
  'fi': "poi2",
  'sv': "evenemax",
}

class SUBIEventMapper (Mapper):
  def __init__(self, session):
    Mapper.__init__(self, session)
    
  def convert_props(self, doc, fromprops, toprop, move=True):
    vals = []
    for prop in fromprops:
      vals += doc.getMetadata(prop)
      if move: doc.clearMetadata(prop)
    for val in vals:
      doc.setMetadata(toprop, val)
    return vals

  def process(self, doc):
    lookup = self._session.getLookupService()

    # transform Agricola event to generic event schema

    types = doc.getMetadata(RDF.type)
    if AGRICOLA.Event in types or MUSEUM.Event in types or EVENT.Event in types:
      # sometimes the graph needs to be accessed directly in the code below
      graph = doc.getMetadataGraph()

      # RDF.type
      doc.clearMetadata(RDF.type)
      doc.setMetadata(RDF.type, EVENT.Event)
#      doc.setMetadata(RDF.type, ICAL.Vevent)
      
      texts = []
      # skos:prefLabel -> ical:summary
      texts += self.convert_props(doc, [SKOS.prefLabel], ICAL.summary)
      
      # dc:description -> ical:description
      texts += self.convert_props(doc, [DC.description], ICAL.description)
      
      # assign subjects using ARPA
      for lang, proj in ARPAPROJECTS.items():
        texts = []
        texts += [s for s in doc.getMetadata(ICAL.summary) if s.language == lang]
        texts += [s for s in doc.getMetadata(ICAL.description) if s.language == lang]
        texts += [s for s in doc.getMetadata(EVENT.longDescription) if s.language == lang]
        text = "\n".join(texts)

        if text.strip() != '':
          for uri in assign_terms(text, proj):
            doc.setMetadata(DCTERMS.subject, uri)
      
      # agricola-schema:locatedIn -> location/locality
      locations = doc.getMetadata(AGRICOLA.locatedIn)
      doc.clearMetadata(AGRICOLA.locatedIn)
      if not locations:
        orgs = doc.getMetadata(MUSEUM.organizer)
        locations = [graph.value(org, MUSEUM.locatedIn, None, any=True) for org in orgs]
      for loc in locations:
        # the argument for urllib cannot be unicode, so encoding it as UTF-8 first
        # see http://bugs.python.org/issue8136 and its attached patch
        municipality = urllib.unquote(loc.split('pp_')[-1].encode('UTF-8')).decode('UTF-8')
        
        adr = getBNode()
        doc.setMetadataTriple(adr, RDF.type, VCARD.Address)
        doc.setMetadataTriple(adr, VCARD.locality, Literal(municipality))

        # look up the municipality in Kunnat ontology and store hits using dct:spatial
        municipalities = lookup.lookup(doc, 'kunnat.kunnat', municipality)
        for municip in municipalities:
          doc.setMetadataTriple(adr, DCTERMS.spatial, municip)

        doc.setMetadataInstance(ICAL.location, VCARD.VCard, VCARD.adr, adr)
        
        # clean up unused Place instance
        for p,o in graph.predicate_objects(loc):
          graph.remove((loc, p, o))
      
      # copy opening times to ical:dtstart and ical:dtend
      opentimes = doc.getMetadata(AGRICOLA.open)
      if not opentimes:
        opentimes = doc.getMetadata(MUSEUM.open)
      for opentime in opentimes:
        start = graph.value(opentime, TIME.earliestStart, None, any=True)
        if start is not None: doc.setMetadata(ICAL.dtstart, start)
        end = graph.value(opentime, TIME.latestEnd, None, any=True)
        if end is not None: doc.setMetadata(ICAL.dtend, end)
      
      # sivuUrl -> ical:url
      # need to convert the URL to URIRef
      sivuUrl = URIRef("http://kulttuurisampo.fi/annotaatio#sivuUrl")
      urls = doc.getMetadata(sivuUrl)
      doc.clearMetadata(sivuUrl)
      for url in urls:
        doc.setMetadata(ICAL.url, URIRef(url))
      
      # organizer -> ical:organizer
      self.convert_props(doc, [AGRICOLA.organizer, MUSEUM.organizer], ICAL.organizer)
      
      # museum:fees -> event:fee
      self.convert_props(doc, [MUSEUM.fees], EVENT.fee)

      # *:open -> dct:temporal
      self.convert_props(doc, [AGRICOLA.open,MUSEUM.open], DCTERMS.temporal)


    doc.setCompleted('map')
    self._session.schedule(doc)
    return True

  def finish(self):
    pass
